import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { Observable } from 'rxjs';

import { Area, AreaService } from '@core/system';
import { NzTreeNode, NzFormatEmitEvent, NzTreeNodeOptions } from 'ng-zorro-antd/tree';

@Component({
  selector: 'app-system-area-tree',
  templateUrl: './area-tree.component.html'
})
export class AreaTreeComponent implements OnInit, OnChanges {
  @Input() parentCodes?: string;
  @Output() readonly selectEvent: EventEmitter<Area> = new EventEmitter<Area>();

  nodes: NzTreeNodeOptions[] = [];
  firstNode?: NzTreeNodeOptions;
  selectedNode?: NzTreeNode;

  constructor(private areaSrc: AreaService) {}

  ngOnInit(): void {}

  ngOnChanges(changes: SimpleChanges): void {
    this.nodes = [];
    this.firstNode = this.createFirstNode();
    this.nodes.push(this.firstNode);
  }

  createFirstNode(): NzTreeNodeOptions {
    return { title: '全部', key: '-1', area: null, expanded: true, selected: true };
  }

  loadFirstData(): Observable<Area[]> {
    let obser: Observable<Area[]>;
    if (this.parentCodes) {
      const codes = this.parentCodes.split(',').map(s => s.trim());
      obser = this.areaSrc.getByCodes(codes);
    } else {
      obser = this.areaSrc.getTop();
    }

    return obser;
  }

  nzEvent(event: NzFormatEmitEvent): void {
    const node = event.node;
    if (event.eventName === 'expand') {
      if (node?.getChildren().length === 0 && node?.isExpanded) {
        this.loadChild(node);
      }
    }

    this.selectEvent.emit(node?.origin['area']);
  }

  reLoad(): void {
    if (!this.selectedNode) {
      return;
    }

    this.selectedNode.clearChildren();
    this.loadChild(this.selectedNode);
  }

  loadChild(node: NzTreeNode): void {
    const area = node.origin['area'];
    let obser: Observable<Area[]>;
    if (area) {
      obser = this.areaSrc.getChildren(area.id);
    } else {
      obser = this.loadFirstData();
    }

    obser.subscribe(areas => {
      node.addChildren(areas.map(area => area.toNzTreeNodeOptions()));
      this.selectedNode = node;
    });
  }
}
